class RangeModule:

    def __init__(self, r=None):
        if r is None:
            r = []
        self.range = r  # [(l1, r1), (l2, r2)]
        self.min = None
        self.max = None

    def is_in_range(self, left, right):
        for rg in self.range:
            if left >= rg[0] and right <= rg[1]:
                return rg
        return False

    def is_overlap(self, left, right):
        overlap_ranges = []
        for rg in self.range:
            if rg[0] <= left < rg[1] or rg[0] < right <= rg[1]:
                overlap_ranges.append(rg)
            elif left < rg[0] and right >= rg[1]:
                overlap_ranges.append(rg)
        if overlap_ranges:
            return overlap_ranges
        else:
            return False

    def merge_range(self):
        new_range = []
        index = 0
        total = len(self.range)
        if total < 2:
            return
        while True:
            if self.range[index][1] >= self.range[index + 1][0]:
                merged = (self.range[index][0], self.range[index + 1][1])
                new_range.append(merged)
                index += 2
            else:
                new_range.append(self.range[index])
                index += 1
            if index >= total:
                break
            if index == len(self.range) - 1:
                new_range.append(self.range[index])
                break
        self.range = new_range

    def addRange(self, left: int, right: int) -> None:
        if self.min is None and self.max is None:
            self.min = left
            self.max = right
            self.range.append((left,right))
            return
        else:
            overlap = self.is_overlap(left, right)
            if overlap:
                if self.is_in_range(left, right):
                    return
                if overlap[0][0] <= left < overlap[0][1] and overlap[-1][0] <= right < overlap[-1][1]:
                    self.range.insert(self.range.index(overlap[0]), (overlap[0][0], overlap[-1][1]))
                if left <= overlap[0][0]:
                    self.range.insert(self.range.index(overlap[0]), (left, max(overlap[-1][1], right)))
                if overlap[0][0] <= left < overlap[0][1] and right >= overlap[-1][1]:
                    self.range.insert(self.range.index(overlap[0]), (min(overlap[0][0], left), max(overlap[-1][1], right)))
                for i in overlap:
                    self.range.remove(i)
            else:
                new_range = (left, right)
                if self.is_in_range(left, right):
                    return
                for i in self.range:
                    if right <= i[0]:
                        self.range.insert(self.range.index(i), new_range)
                        return
                self.range.append(new_range)
        self.merge_range()


    def queryRange(self, left: int, right: int) -> bool:
        # print(self.range)
        for i in self.range:
            if left >= i[0] and right <= i[1]:
                return True
        return False

    def removeRange(self, left: int, right: int) -> None:
        rm_ranges = []
        new_range = []
        for i in self.range:
            if i[0] <= left < i[1]:
                new_range.append((i[0], left))
                rm_ranges.append(i)
            if i[0] <= right < i[1]:
                new_range.append((right, i[1]))
                rm_ranges.append(i)
            if left <= i[0] and right >= i[1]:
                rm_ranges.append(i)
        if rm_ranges:
            insert_pos = self.range.index(rm_ranges[0])
            for i in new_range:
                self.range.insert(insert_pos, i)
                insert_pos += 1
        for i in set(rm_ranges):
            self.range.remove(i)
